//
//  JLCFHttpManager.m
//  QTZ
//
//  Created by ski on 2017/7/6.
//  Copyright © 2017年 ski. All rights reserved.
//

#import "JLCFHttpManager.h"
#import "JLCFHTTPResponseSerializer.h"
#import "JLCFApp.h"
#import "MBProgressHUD.h"
#import "JLCFRegisterService.h"
#import "rmMqyfJLCFLoginAndRegisterControllerFbzYtj.h"

#define REQUEST_TIMEOUT 10.f

#define TIP_NO_NETWORK              @"你的网络好像不是很给力哦"
#define TIP_REQUEST_FAILED          @"服务器开小差了，休息一下马上回来"

@interface JLCFHttpManager ()
@property (nonatomic, assign) BOOL debugMode;
@property (nonatomic, strong) MBProgressHUD *noticeView;
@property (nonatomic, strong) MBProgressHUD *networkNotice;
@property (nonatomic, assign) BOOL hideLoginView;

@end

@implementation JLCFHttpManager

- (id)init {
    self = [super init];
    if (self) {
        
        _httpManager = [[AFHTTPRequestOperationManager alloc] init];
        _httpManager.responseSerializer = [JLCFHTTPResponseSerializer serializer];
        _httpManager.requestSerializer.timeoutInterval = REQUEST_TIMEOUT;//请求超时

        self.networkStatus = [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:AFNetworkingReachabilityDidChangeNotification object:nil];
        
    }
    
    
    return self;
}

#pragma nark - MBHUD - 
- (void)showInView:(UIView *)view
{
    [self hideHud];
    _noticeView = [[MBProgressHUD alloc] initWithView:view];
    [view addSubview:_noticeView];
    _noticeView.userInteractionEnabled = YES;
    _noticeView.bezelView.color = QTZ_Black;
    _noticeView.alpha = .8;
    if (@available(iOS 9.0, *)) {
        [UIActivityIndicatorView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]].color = QTZ_White;
    } else {
        // Fallback on earlier versions
    }
    _noticeView.mode = MBProgressHUDModeIndeterminate;
    _noticeView.detailsLabel.font = FONT(14);
    _noticeView.detailsLabel.textColor = QTZ_White;
    _noticeView.detailsLabel.text = @"加载中...";
    _noticeView.margin = 12.f;
    [_noticeView showAnimated:YES];
}

- (void)hideHud
{
    [_noticeView removeFromSuperview];
    [_noticeView hideAnimated:YES afterDelay:0.f];
}

- (void)showNetworkStatus:(NSString *)status
{
    [self.networkNotice removeFromSuperview];
    if (!self.networkNotice) {
        self.networkNotice = [[MBProgressHUD alloc] initWithView:[JinLiCaiFuApplicationEntrace shareEntrance].window];
        self.networkNotice.userInteractionEnabled = NO;
        self.networkNotice.mode = MBProgressHUDModeText;
        self.networkNotice.centerY = FULL_HEIGHT / 2;
        self.networkNotice.detailsLabel.font = FONT(14);
        self.networkNotice.detailsLabel.textColor = QTZ_White;
        self.networkNotice.margin = 20;
        self.networkNotice.bezelView.color = QTZ_Black;
    }
    if (!self.networkNotice.superview) {
        [[JinLiCaiFuApplicationEntrace shareEntrance].window addSubview:self.networkNotice];
    }
    self.networkNotice.detailsLabel.text = status;
    [self.networkNotice showAnimated:YES];
    [self.networkNotice hideAnimated:YES afterDelay:1.5];
}

#pragma mark - request method
- (void)getDataWithUrl:(NSString *)url params:(NSDictionary *)params loadingInView:(UIView *)view success:(SuccessBlock)success failure:(FailureBlock)failure {
    
    [self requestDataWithMethod:@"GET" url:url params:params loadingInView:view success:success failure:failure];
}

- (void)postDataWithUrl:(NSString *)url
                 params:(NSDictionary *)params
          loadingInView:(UIView *)view
                success:(void (^)(NSDictionary *result))success
                failure:(void (^)(NSString *status))failure {
    
    [self requestDataWithMethod:@"POST"
                            url:url
                         params:params
                  loadingInView:view
                        success:success failure:failure];
}

- (void)requestDataWithMethod:(NSString *)method url:(NSString *)url params:(NSDictionary *)params loadingInView:(UIView *)view success:(SuccessBlock)success failure:(FailureBlock)failure {
    
    [self requestWithUrl:url params:params method:method view:view success:success failure:failure loginCheck:YES];
}


- (void)requestWithUrl:(NSString *)url params:(NSDictionary *)params method:(NSString *)method view:(UIView *)view success:(SuccessBlock)success failure:(FailureBlock)failure loginCheck:(BOOL)loginCheck {
    
    __weak JLCFHttpManager *wself = self;
    
    // 等待框
    if (view && [view isKindOfClass:[UIView class]]) {
        [self showInView:view];
    }
    
    NSDictionary *requestParams = [JLCFHttpManager generateSystemParamsWithApiParams:params];
    NSString *_path = [url addParamsToUrlFromDictionary:requestParams];
    DBG(@"请求链接：%@", _path);
    DBG(@"请求参数：%@", params);
    
    NSError *error;
    
    
    NSMutableURLRequest *request = [_httpManager.requestSerializer requestWithMethod:method URLString:_path  parameters:params error:&error];
    if ([JLCFRegisterService shareService].hasToken) {
        [request setValue:[JLCFRegisterService shareService].token forHTTPHeaderField:@"token"];
//        [request setValue:[JLCFRegisterService shareService].shareId forHTTPHeaderField:@"uid"];
    }
//    DBG(@"请求头 : %@", request.allHTTPHeaderFields);
    NSTimeInterval requestTime = [NSDate timeIntervalSinceReferenceDate] * 1000;
    
    
    void (^responseSuccess)(AFHTTPRequestOperation*, id) = [self successBlockForAFNetworkingBeginAtTime:requestTime loginCheck:loginCheck inView:view withUrl:url success:success failure:failure repeat:^{
        [wself requestWithUrl:url params:params method:method view:view success:success failure:failure loginCheck:loginCheck];
    }];
    
    void (^failureResponse)(AFHTTPRequestOperation *, NSError *) = [self failureBlockForAFNetworkingBeginAtTime:requestTime inView:view withUrl:url success:success failure:failure];
    
    AFHTTPRequestOperation *operation = [_httpManager HTTPRequestOperationWithRequest:request success:responseSuccess failure:failureResponse];
    [_httpManager.operationQueue addOperation:operation];
}

- (void)postMultipartFormDataWithUrl:(NSString *)url params:(NSDictionary *)params constructingBodyWithBlock:(void(^)(id<AFMultipartFormData> formData))constructingBlock loadingInView:(UIView *)view success:(void (^)(NSDictionary *result))success failure:(void (^)(NSString *status))failure
{
    // 等待框
    if (view && [view isKindOfClass:[UIView class]]) {
        [self showInView:view];
    }

    
    NSTimeInterval requestTime = [NSDate timeIntervalSinceReferenceDate] * 1000;
    
    __weak typeof(self) wself = self;
    
    void (^responseSuccess)(AFHTTPRequestOperation*, id) = [self successBlockForAFNetworkingBeginAtTime:requestTime loginCheck:YES inView:view withUrl:url success:success failure:failure repeat:^{
        [wself postMultipartFormDataWithUrl:url params:params constructingBodyWithBlock:constructingBlock loadingInView:view success:success failure:failure];
    }];
    
    void (^failureResponse)(AFHTTPRequestOperation *, NSError *) = [self failureBlockForAFNetworkingBeginAtTime:requestTime inView:view withUrl:url success:success failure:failure];
    
    NSDictionary *requestParams = [JLCFHttpManager generateSystemParamsWithApiParams:params];
    NSString *_path = [url addParamsToUrlFromDictionary:requestParams];
    DBG(@"请求链接：%@", _path);
    DBG(@"请求参数：%@", params);
    
    NSError *error;
    NSMutableURLRequest *request = [_httpManager.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:_path parameters:params constructingBodyWithBlock:constructingBlock error:&error];
    AFHTTPRequestOperation *operation = [_httpManager HTTPRequestOperationWithRequest:request success:responseSuccess failure:failureResponse];
    [_httpManager.operationQueue addOperation:operation];
}

- (AFHTTPRequestOperation *)postWithManager:(AFHTTPRequestOperationManager *)manager url:(NSString *)url params:(NSDictionary *)params constructingBodyWithBlock:(void(^)(id<AFMultipartFormData> formData))constructingBlock loadingInView:(UIView *)view success:(void (^)(NSDictionary *result))success failure:(void (^)(NSString *status))failure
{
    // 等待框
    if (view && [view isKindOfClass:[UIView class]]) {
        [self showInView:view];
    }
    
    NSTimeInterval requestTime = [NSDate timeIntervalSinceReferenceDate] * 1000;
    
    __weak typeof(self) wself = self;
    
    void (^responseSuccess)(AFHTTPRequestOperation*, id) = [self successBlockForAFNetworkingBeginAtTime:requestTime loginCheck:YES inView:view withUrl:url success:success failure:failure repeat:^{
        [wself postMultipartFormDataWithUrl:url params:params constructingBodyWithBlock:constructingBlock loadingInView:view success:success failure:failure];
    }];
    
    void (^failureResponse)(AFHTTPRequestOperation *, NSError *) = [self failureBlockForAFNetworkingBeginAtTime:requestTime inView:view withUrl:url success:success failure:failure];
    
    NSDictionary *requestParams = [JLCFHttpManager generateSystemParamsWithApiParams:params];
    NSString *_path = [url addParamsToUrlFromDictionary:requestParams];
    DBG(@"请求链接：%@", _path);
    DBG(@"请求参数：%@", params);
    
    NSError *error;
    NSMutableURLRequest *request = [_httpManager.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:_path parameters:params constructingBodyWithBlock:constructingBlock error:&error];
    AFHTTPRequestOperation *operation = [_httpManager HTTPRequestOperationWithRequest:request success:responseSuccess failure:failureResponse];
    [manager.operationQueue addOperation:operation];
    
    return operation;
}

#pragma mark - generate blocks

- (void (^)(AFHTTPRequestOperation *operation, id responseObject))successBlockForAFNetworkingBeginAtTime:(NSTimeInterval)beginTime loginCheck:(BOOL)loginCheck inView:(UIView *)view withUrl:(NSString *)url success:(void (^)(NSDictionary *result))success failure:(void (^)(NSString *status))failure repeat:(void (^)(void))repeat {

    weakify(self);
    void (^responseSuccess)(AFHTTPRequestOperation*, id) = ^(AFHTTPRequestOperation *operation, id responseObject){
        strongify(self);
        NSDictionary *responseDictionary = [responseObject copy];

        NSInteger code = [[responseDictionary safeObjectForKey:@"code"] integerValue];
        if (code == 506 || code == 500 || code == 507) {
            //token失效
            rmMqyfJLCFLoginAndRegisterControllerFbzYtj *vc = [rmMqyfJLCFLoginAndRegisterControllerFbzYtj new];
            if (![[JinLiCaiFuApplicationEntrace shareEntrance] isContainVC:@"LoginAndRegisterController"]) {
                [[[JinLiCaiFuApplicationEntrace shareEntrance] currentNavController] pushViewController:vc animated:YES];
            }
            [[JLCFRegisterService shareService] logOut];
        }
        
        DBG(@"返回数据: %@, HTTPHeaderFields : %@", responseDictionary, operation.response.allHeaderFields);
        [JLCFRegisterService shareService].token = [operation.response.allHeaderFields safeObjectForKey:@"token"];
        success(responseDictionary);
        // 隐藏等待框
        if (view) {
            [self hideHud];
        }
    };
    return responseSuccess;
}


- (void (^)(AFHTTPRequestOperation *operation, id responseObject))failureBlockForAFNetworkingBeginAtTime:(NSTimeInterval)beginTime inView:(UIView *)view withUrl:(NSString *)url success:(void (^)(NSDictionary *result))success failure:(void (^)(NSString *status))failure
{
    weakify(self);
    void (^failureResponse)(AFHTTPRequestOperation *, NSError *) = ^(AFHTTPRequestOperation *operation, id status){
        strongify(self);
        // 隐藏等待框
        if (view) {
            [self hideHud];
        }
        NSInteger error = ((NSError *)status).code;
        if (error != 200) {
            if (AFNetworkReachabilityStatusNotReachable == [[JLCFHttpManager sharedManager] networkStatus]) {
                failure(@"当前无网络连接，请稍后重试");
            } else {
                failure(@"请求失败，请稍后重试");
//                NSLog(@"%@", [NSString stringWithFormat:@"test       -----------%ld",error]);
            }
        }

        
    };
    
    return failureResponse;
    
}

#pragma mark cancel request
- (void)cancelGetRequestWithUrl:(NSString *)url
{
    [self cancelAllHTTPOperationsWithMethod:@"GET" url:url];
}

- (void)cancelAllHTTPOperationsWithMethod:(NSString *)method url:(NSString *)url
{
    NSError *error;
    
    NSString *pathToBeMatched = [[[_httpManager.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:url] absoluteString] parameters:nil error:&error] URL] path];
    
    for (NSOperation *operation in [_httpManager.operationQueue operations]) {
        if (![operation isKindOfClass:[AFHTTPRequestOperation class]]) {
            continue;
        }
        BOOL hasMatchingMethod = !method || [method  isEqualToString:[[(AFHTTPRequestOperation *)operation request] HTTPMethod]];
        BOOL hasMatchingPath = [[[[(AFHTTPRequestOperation *)operation request] URL] path] isEqual:pathToBeMatched];
        
        if (hasMatchingMethod && hasMatchingPath) {
            [operation cancel];
        }
    }
    
}

#pragma mark - class method
+ (instancetype)sharedManager
{
    static JLCFHttpManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[JLCFHttpManager alloc] init];
    });
    
    return manager;
}

+ (void)setDebugMode:(BOOL)debugMode
{
    [JLCFHttpManager sharedManager].debugMode = debugMode;
}

+ (void)startMonitoringNetworkStatus
{
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
}



+ (NSMutableDictionary *)generateSystemParamsWithApiParams:(NSDictionary *)params {
    
    //接口传入参数
    NSMutableDictionary *totalParams = [NSMutableDictionary dictionaryWithDictionary:params];
    
    //基础系统参数
    NSMutableDictionary *systemParams = [[JLCFHttpManager systemParams] mutableCopy];
    
    //加上系统参数
    [totalParams addEntriesFromDictionary:systemParams];
    
    //key 排序
    NSArray *keys = [totalParams allKeys];
    if ([keys containsObject:HIDELOGINVIEW]) {
        [JLCFHttpManager sharedManager].hideLoginView = YES;
    } else {
        [JLCFHttpManager sharedManager].hideLoginView = NO;
    }
    NSArray *sortedkeys = [keys sortedArrayUsingSelector:@selector(compare:)];
    
    
    //拼接参数
    NSMutableString *paramsStr = [NSMutableString string];
    
    for (NSString *key in sortedkeys) {
        if (![[totalParams objectForKey:key] isKindOfClass:[NSArray class]]) {
            [paramsStr appendFormat:@"%@",totalParams[key]];
        }
    }
    
    DBG(@"拼接参数:%@", paramsStr);
    
    
    return systemParams;
}

+ (NSDictionary *)systemParams
{
    NSMutableDictionary *_params = [NSMutableDictionary dictionary];
    
    if ([JLCFRegisterService shareService].hasToken) {
//        [_params setSafeObject:[JLCFRegisterService shareService].token forKey:@"uid"];
    }
    //马甲包
    majiabao;
    
    return _params;
}

#pragma mark - notification
- (void)reachabilityChanged:(NSNotification *)notification
{
    AFNetworkReachabilityStatus status = [notification.userInfo[AFNetworkingReachabilityNotificationStatusItem] integerValue];
    
    if ( self.networkStatus != AFNetworkReachabilityStatusUnknown ) {
        
        NSString *notice = @"";
        
        if ( AFNetworkReachabilityStatusReachableViaWiFi == status ) {
            
            [JLCFHttpManager sharedManager].isUnderWifi = YES;
            notice = @"当前处于wifi网络";
            
        } else if ( AFNetworkReachabilityStatusReachableViaWWAN == status ){
            
            [JLCFHttpManager sharedManager].isUnderWifi = NO;
            notice = @"当前处于非wifi网络";
            
        } else if ( AFNetworkReachabilityStatusNotReachable == status ) {
            
            [JLCFHttpManager sharedManager].isUnderWifi = NO;
            notice = @"没有网络";
            
        }
    
        //提示
//        [self showNetworkStatus:notice];
    }
    
    
    [[JLCFHttpManager sharedManager] setNetworkStatus:status];

    if ( AFNetworkReachabilityStatusReachableViaWiFi == status ) {
        [JLCFHttpManager sharedManager].isUnderWifi = YES;
    }

}

@end
